package cn.bjc.basic.service.impl;

import cn.bjc.basic.constant.RegisterConstant;
import cn.bjc.basic.exception.BusinessException;
import cn.bjc.basic.service.IVerifyCodeService;
import cn.bjc.basic.util.SmsSendUtil;
import cn.bjc.basic.util.StrUtils;
import cn.bjc.basic.util.VerifyCodeUtils;
import cn.bjc.user.domain.User;
import cn.bjc.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private UserMapper userMapper;
    
    //图形验证码
    @Override
    public String getVerifyCode(String key) {
        //1.校验
        if (StringUtils.isEmpty(key)){
            throw new BusinessException("参数有误");
        }
        
        //2.生成随机验证码
        String code = StrUtils.getComplexRandomString(4);
        
        //3.随机验证码存入redis中,设置过期时间3分钟
        redisTemplate.opsForValue().set(key, code, 3, TimeUnit.MINUTES);
        
        //4.生成一个base64位字符串
        return VerifyCodeUtils.verifyCode(100, 40, code);
    }
    
    //短信验证码
    @Override
    public void smsCode(Map<String, String> map) {

        String phone = map.get("phone");//手机号
        String imageCode = map.get("imageCode");//图形验证码
        String imageCodeKey = map.get("imageCodeKey");//图形验证码对应的key
        
        //1.校验:参i数不为空
        if(StringUtils.isEmpty(phone)|| 
           StringUtils.isEmpty(imageCode)||
           StringUtils.isEmpty(imageCodeKey)
        ){
            throw new BusinessException("参数不能为空");
        }
        //2.图形验证码正确
        Object obj = redisTemplate.opsForValue().get(imageCodeKey);
        
        if (obj==null) {
            throw new BusinessException("图形验证码过期,请重新获取");
        }
        //equalsIgnoreCase不区分大小写校验
        if(!obj.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码输入错误,请重新获取");
        }
        //3.手机是否被注册过    查询表:user
        User user = userMapper.findByPhone(phone);
        if(user!=null){
            throw new BusinessException("该手机号已经被注册,请直接登录");
        }

        /**
         * key:手机号+业务键  业务键:最好是常量
         * value:code+时间戳
         * 
         */
        //4.判断是否是第一次发送请求,或者是验证码过期   从redis中获取
        Object value = redisTemplate.opsForValue().get(phone + RegisterConstant.PHONEREGISTER);
        
        String code = null;
        //4.1 如果取不到,没有发送过,后去过期了,直接生成一个新的验证码保存到redis
        if(value==null){//没取到
            code = StrUtils.getComplexRandomString(6);
        }else{
            //4.2如果取到了,判断是否超过1分钟
            String redisTime = value.toString().split(":")[1];
            long ltime = Long.valueOf(redisTime);
            //4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送。
            if(System.currentTimeMillis()-ltime < 1*60*1000){
                throw new BusinessException("一分钟之内不允许发送多次!");
            }else {
                //4.2.2 如果超过1分钟,刷新过期时间
                code = value.toString().split(":")[0];
            }
        }
        
        //4.2.2把code存入redis中
        redisTemplate.opsForValue().set(
                phone+RegisterConstant.PHONEREGISTER,
                code+":"+System.currentTimeMillis(),
                3,
                TimeUnit.MINUTES);
        
        //5.发送短信
        //SmsSendUtil.smsSend(phone, "您的验证码为:"+code+",请在3分钟内使用!");
        System.out.println("您的验证码为:"+code+",请在3分钟内使用!");
    }

    @Override
    public void binderSmsCode(Map<String, String> map) {

        String phone = map.get("phone");//手机号


        //1.校验:参i数不为空
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("手机号不能为空");
        }
        
        //4.判断是否是第一次发送请求,或者是验证码过期   从redis中获取
        Object value = redisTemplate.opsForValue().get(phone + RegisterConstant.WXBINDER);

        String code = null;
        //4.1 如果取不到,没有发送过,后去过期了,直接生成一个新的验证码保存到redis
        if(value==null){//没取到
            code = StrUtils.getComplexRandomString(6);
        }else{
            //4.2如果取到了,判断是否超过1分钟
            String redisTime = value.toString().split(":")[1];
            long ltime = Long.valueOf(redisTime);
            //4.2.1： 如果没超过1分钟，直接提示用户，1分钟之内不能多次发送。
            if(System.currentTimeMillis()-ltime < 1*60*1000){
                throw new BusinessException("一分钟之内不允许发送多次!");
            }else {
                //4.2.2 如果超过1分钟,刷新过期时间
                code = value.toString().split(":")[0];
            }
        }

        //4.2.2把code存入redis中
        redisTemplate.opsForValue().set(
                phone+RegisterConstant.WXBINDER,
                code+":"+System.currentTimeMillis(),
                3,
                TimeUnit.MINUTES);
        
        //5.发送短信
        //SmsSendUtil.smsSend(phone, "您的验证码为:"+code+",请在3分钟内使用!");
        System.out.println("您的验证码为:"+code+",请在3分钟内使用!");
    }
}
